<?php
//我们公司和外部公司有业务关系，通过一种数据格式来通信。而这种通信方式可能会变。创建一个管理者类和一个编码器类

//第一版 工厂模式 但是这种方式有缺陷，就是比如我需要加入页眉和页脚描述的时候，会让存在很多条件语句
/*abstract class ApptEncoder{
    abstract function encode();
}

class BloggsApptEncoder extends ApptEncoder{
    public function encode()
    {
        return '把数据编码成bloggs格式';
    }
}

class MegaApptEncoder extends ApptEncoder{
    public function encode()
    {
        return '把数据编码成Mega格式';
    }
}
class CommsManager{
    const BLOGGS = 1;
    const MEGA = 2;
    private $mode = 1;
    public function __construct($mode)
    {
        $this->mode = $mode;
    }

    //这个是当需求变动，加入头的时候，又会多出判断语句。（如果在加入尾，会继续多出）
    public function getHeaderText(){
        switch($this->mode){
            case 1:
                return 'blog 头';
                break;
            default:
                return 'mega 头';
        }
    }

    public function getApptEncoder(){
        switch($this->mode){
            case 1:
                return new BloggsApptEncoder();
                break;
            default:
                return new MegaApptEncoder();
        }
    }
}
$comms = new CommsManager(CommsManager::MEGA);
$apptEncoder = $comms->getApptEncoder();
print $apptEncoder->encode();*/

//第二版，我们需要相对轻松的加入一些新的产品类型,因此用了简单工厂。但是简单工厂有问题。1.会造成很多子类。2.会有很多重复代码。
abstract class ApptEncoder{
    abstract function encode();
}

class BloggsApptEncoder extends ApptEncoder{
    public function encode()
    {
        return '把数据编码成bloggs格式';
    }
}

class MegaApptEncoder extends ApptEncoder{
    public function encode()
    {
        return '把数据编码成Mega格式';
    }
}

abstract class CommsManger{
    abstract function getHeaderText();
    abstract function getApptEncoder();
    abstract function getFootText();
}

class BloggsCommsManger extends CommsManger{
    public function getApptEncoder()
    {
        return new BloggsApptEncoder();
    }
    public function getFootText()
    {
        return 'bloggs 尾';
    }
    public function getHeaderText()
    {
        return 'bloggs 头';
    }
}

class MegaCommsManger extends CommsManger{
    public function getApptEncoder()
    {
        return new MegaApptEncoder();
    }
    public function getFootText()
    {
        return 'mega 尾';
    }
    public function getHeaderText()
    {
        return 'mega 头';
    }
}